package short_semester.questionnaire_planet.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import short_semester.questionnaire_planet.dao.UserDao;
import short_semester.questionnaire_planet.entity.User;
import short_semester.questionnaire_planet.response.CommonResponse;
import short_semester.questionnaire_planet.response.UserResponse.loginResponse;
import short_semester.questionnaire_planet.response.UserResponse.userInfo;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.*;

@RestController
@RequestMapping("/api")
public class UserController {

    @Autowired
    private UserDao userDao;

    @Autowired
    JavaMailSenderImpl mailSender;


    @PostMapping("/getAllUsers")
    public CommonResponse getAllUsers() {
        CommonResponse cr = new CommonResponse();
        cr.setData(userDao.findAll());
        cr.setCode(0);
        cr.setMsg("Success");
        return cr;
    }


    //实现md5加密
    public static String getMD5String(String str) {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes());
            // digest()最后确定返回md5 hash值，返回值为8位字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            //一个byte是八位二进制，也就是2位十六进制字符（2的8次方等于16的2次方）
            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @PostMapping("/login")
    public CommonResponse login(
            @RequestParam("email") String email,
            @RequestParam("password") String password){

        CommonResponse cr = new CommonResponse();
        try {
            User user = userDao.findByEmail(email);
            if (user == null) {
                cr.setCode(2);
                cr.setMsg("无此邮箱");
                return cr;
            }
            String passwordMD5 = user.getPassword();

            if (passwordMD5.equals(getMD5String(password))) {
                cr.setCode(0);
                cr.setMsg("登录成功");
                int id = userDao.findByEmail(email).getId();
                loginResponse loginResponse = new loginResponse(id);
                cr.setData(loginResponse);
            } else {
                cr.setCode(1);
                cr.setMsg("登录失败，密码错误");
            }
        } catch (Exception e){
            cr.error(e.getMessage());
        }

        return cr;
    }



    //邮箱验证
    @PostMapping("/register/sendCode")
    public CommonResponse emailVerification(
            @RequestParam("email") String email,
            HttpSession session) throws MessagingException {
        CommonResponse cr = new CommonResponse();
        try {
            Boolean isEmailRepeat = false;
            if (userDao.findByEmail(email) == null) {
                isEmailRepeat = true;
            }

            if (isEmailRepeat) {
                String emailCode = ((int) (1 + Math.random() * (1000000 - 1))) + "";
                Properties properties = new Properties();
                //如果连接25端口以外的端口就必须有这个参数设置,且配置文件中的配置需要手动导入到                    JavaMailSenderImpl才能在其中使用
                properties.put("mail.smtp.ssl.enable", true);
                mailSender.setJavaMailProperties(properties);
                MimeMessage mimeMessage = mailSender.createMimeMessage();
                MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
                mimeMessageHelper.setSubject("问卷星球验证码");

                mimeMessageHelper.setText("验证码是: " + emailCode);
                mimeMessageHelper.setTo(email);
                mimeMessageHelper.setFrom("lsy763324424@126.com");
                mailSender.send(mimeMessage);

                cr.setCode(0);
                cr.setMsg("验证码发送成功");
                session.setAttribute("TrueEmailCode", emailCode);
            } else {
                cr.setCode(1);
                cr.setMsg("邮箱重复");
            }
        } catch (Exception e){
            cr.error(e.getMessage());
        }
        return cr;
    }

    //用户注册
    @PostMapping("/register/commit")
    public CommonResponse register(
            @RequestParam("username") String username,
            @RequestParam("password1") String password1,
            @RequestParam("password2") String password2,
            @RequestParam("email") String email,
            @RequestParam("emailCode") String emailCode,
            HttpSession session){
        CommonResponse cr = new CommonResponse();

        try {
            //真正的正确验证码，在session中取得
            String TrueEmailCode = (String) session.getAttribute("TrueEmailCode");

            if(!password1.equals(password2)){
                cr.setCode(2);
                cr.setMsg("两次输入的密码不相同");
            }

            else if (emailCode.equals(TrueEmailCode)) {

                User user = new User(null, username, getMD5String(password1), email, null);
                userDao.save(user);

                cr.setCode(0);
                cr.setMsg("验证码正确，注册成功");
            } else {

                cr.setCode(1);
                cr.setMsg("验证码不符，错误");
            }
        }catch (Exception e){
            cr.error(e.getMessage());
        }

        return cr;

    }

    //找回密码的邮箱验证
    @PostMapping("/retrieve/verify")
    public CommonResponse retrieveEmailVerification(
            @RequestParam("email") String email,
            HttpSession session) throws MessagingException {

        CommonResponse cr = new CommonResponse();
        try {
            Properties properties = new Properties();
            //如果连接25端口以外的端口就必须有这个参数设置,且配置文件中的配置需要手动导入到                    JavaMailSenderImpl才能在其中使用
            properties.put("mail.smtp.ssl.enable", true);
            mailSender.setJavaMailProperties(properties);
            User user = userDao.findByEmail(email);
            if (user == null) {
                cr.setCode(1);
                cr.setMsg("该邮箱未注册");
                return cr;
            }

            String emailCode = ((int) (1 + Math.random() * (1000000 - 1))) + "";

            //设置验证码的开始时间，以实现5分钟验证码过期
            session.setAttribute("starting", new Date());

            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setSubject("问卷星球验证码");

            mimeMessageHelper.setText("验证码是: " + emailCode);
            mimeMessageHelper.setTo(email);
            mimeMessageHelper.setFrom("lsy763324424@126.com");
            mailSender.send(mimeMessage);

            cr.setCode(0);
            cr.setMsg("发送验证码成功");
            session.setAttribute("TrueEmailCode", emailCode);
        }catch (Exception e){
            cr.error(e.getMessage());
        }

        return cr;

    }

    //邮箱验证（找回密码）
    @PostMapping("/retrieve/code")
    public CommonResponse retrieveEmail(
            @RequestParam("emailCode") String emailCode,
            HttpSession session){
        CommonResponse cr = new CommonResponse();
        try {
            String TrueEmailCode = (String) session.getAttribute("TrueEmailCode");
            //发送验证码的时间
            Date beforetime = (Date) session.getAttribute("starting");

            Date now = new Date();
            //五分钟前
            Date date = new Date(now.getTime() - 300000);
            if (date.compareTo(beforetime) == 1) {
                cr.setCode(1);
                cr.setMsg("验证码超过五分钟");
                return cr;
            }

            if (emailCode.equals(TrueEmailCode)) {
                cr.setCode(0);
                cr.setMsg("验证码匹配成功");
            } else {
                cr.setCode(2);
                cr.setMsg("验证码不匹配");
            }
        }catch (Exception e){
            cr.error(e.getMessage());
        }
        return cr;
    }

    //重新设置密码
    @PostMapping("/retrieve/reset")
    public CommonResponse resetPassword(
            @RequestParam("password1") String password,
            @RequestParam("password2") String rePassword,
            @RequestParam("email") String email ) {

        CommonResponse cr = new CommonResponse();
        try {
            if (!password.equals(rePassword)) {
                cr.setCode(1);
                cr.setMsg("密码不相同");
            } else {
                User user = userDao.findByEmail(email);
                user.setPassword(getMD5String(password));
                userDao.save(user);
                cr.setCode(0);
                cr.setMsg("成功");
            }
        }catch (Exception e){
            cr.error(e.getMessage());
        }


        return cr;
    }

    //通过id获取个人信息
    @PostMapping("/user/getInfo")
    public CommonResponse info(
            @RequestParam("id") Integer id){
        CommonResponse cr = new CommonResponse();

        try {
            Optional<User> users = userDao.findById(id);
            User user = users.get();

            if (user == null) {
                cr.setCode(1);
                cr.setMsg("未找到相关用户");
            } else {
                userInfo userInfo = new userInfo(user.getUsername(), user.getPassword(), user.getEmail());

                cr.setCode(0);
                cr.setMsg("成功查询，返回相关信息");
                cr.setData(userInfo);

            }
        }catch (Exception e){
            cr.error(e.getMessage());
        }
        return cr;

    }

    //登录后直接更改密码
    @PostMapping("/user/alter")
    public CommonResponse alterPassword(
            @RequestParam("id") Integer id,
            @RequestParam("password1") String password1,
            @RequestParam("password2") String password2) {
        CommonResponse cr = new CommonResponse();
        try{
            if(!password1.equals(password2)){
                cr.setCode(2);
                cr.setMsg("两次密码不相符");
            }
            else{
                User user = userDao.findById(id).get();
                user.setPassword(getMD5String(password1));
                userDao.save(user);
                cr.setCode(0);
                cr.setMsg("密码修改成功");
            }
        }catch (Exception e){
            cr.error(e.getMessage());
        }


        return cr;
    }
}


